home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Tools & Apps / OS⁄Toolbox / SignatureToApp 1.0 / Source Code / SignatureToApp.c
Encoding:
Text File  |  1991-06-26  |  6.2 KB  |  233 lines  |  [TEXT/MPS ]

  1. ////
  2. ////    SignatureToApp.c        Implementation of the SignatureToApp function.
  3. ////
  4. ////    By Jens Alfke            ©1991 Apple Computer, Inc. All rights reserved.
  5. ////
  6.  
  7.  
  8. #include <Errors.h>
  9. #include <Files.h>
  10. #include <Processes.h>
  11. #include <Folders.h>
  12.  
  13. #include "SignatureToApp.h"
  14.  
  15.  
  16.    ////////////////////////////////////////////////////////////
  17.   //    FindRunningAppBySignature                            //
  18.  //            Search process list for app with this signature//
  19. ////////////////////////////////////////////////////////////
  20. static OSErr
  21. FindRunningAppBySignature( OSType sig, ProcessSerialNumber *psn, FSSpec *fileSpec )
  22. {
  23.     OSErr err;
  24.     ProcessInfoRec info;
  25.     
  26.     psn->highLongOfPSN = 0;
  27.     psn->lowLongOfPSN  = kNoProcess;
  28.     do{
  29.         err= GetNextProcess(psn);
  30.         if( !err ) {
  31.             info.processInfoLength = sizeof(info);
  32.             info.processName = NULL;
  33.             info.processAppSpec = fileSpec;
  34.             err= GetProcessInformation(psn,&info);
  35.         }
  36.     } while( !err && info.processSignature != sig );
  37.  
  38.     if( !err )
  39.         *psn = info.processNumber;
  40.     return err;
  41. }
  42.  
  43.  
  44.    ////////////////////////////////////////////////////////////
  45.   //    GetSysVolume                                        //
  46.  //            Get the vRefNum of the system (boot) volume       //
  47. ////////////////////////////////////////////////////////////
  48. static OSErr
  49. GetSysVolume( short *vRefNum )
  50. {
  51.     long dir;
  52.     
  53.     return FindFolder(kOnSystemDisk,kSystemFolderType,false, vRefNum,&dir);
  54. }
  55.  
  56.  
  57.    ////////////////////////////////////////////////////////////
  58.   //    GetIndVolume                                        //
  59.  //            Get the vRefNum of an indexed on-line volume   //
  60. ////////////////////////////////////////////////////////////
  61. static OSErr
  62. GetIndVolume( short index, short *vRefNum )
  63. {
  64.     ParamBlockRec pb;
  65.     OSErr err;
  66.     
  67.     pb.volumeParam.ioCompletion = NULL;
  68.     pb.volumeParam.ioNamePtr = NULL;
  69.     pb.volumeParam.ioVolIndex = index;
  70.     
  71.     err= PBGetVInfo(&pb,false);
  72.     
  73.     *vRefNum = pb.volumeParam.ioVRefNum;
  74.     return err;
  75. }
  76.  
  77.  
  78.    ////////////////////////////////////////////////////////////
  79.   //    VolHasDesktopDB                                        //
  80.  //            Check if a volume supports desktop DB calls       //
  81. ////////////////////////////////////////////////////////////
  82. static OSErr
  83. VolHasDesktopDB( short vRefNum, Boolean *hasDesktop )
  84. {
  85.     typedef struct {                        // Volume Info Rec; see IM-VI 25-32
  86.         short    vMVersion;
  87.         long    vMAttrib;
  88.         Handle    vMLocalHand;
  89.         long    vMServerAddr;
  90.         long    vMVolumeGrade;
  91.         short    vMForeignPrivID;
  92.     } VolInfoRec;
  93.     const bHasNewDesk = 1L <<12;            // Flag mask for vMAttrib field
  94.     
  95.     HParamBlockRec pb;
  96.     VolInfoRec info;
  97.     OSErr err;
  98.     
  99.     pb.ioParam.ioCompletion = NULL;
  100.     pb.ioParam.ioNamePtr = NULL;
  101.     pb.ioParam.ioVRefNum = vRefNum;
  102.     pb.ioParam.ioBuffer = (Ptr)&info;
  103.     pb.ioParam.ioReqCount = sizeof(VolInfoRec);
  104.     
  105.     err= PBHGetVolParms(&pb,false);            // Get volume info
  106.  
  107.     *hasDesktop = err==noErr && (info.vMAttrib & bHasNewDesk)!=0;
  108.     return err;
  109. }
  110.  
  111.  
  112.    ////////////////////////////////////////////////////////////
  113.   //    FindAppOnVolume                                        //
  114.  //            Ask vol's desktop db for application           //
  115. ////////////////////////////////////////////////////////////
  116. static OSErr
  117. FindAppOnVolume( OSType sig, short vRefNum, FSSpec *file )
  118. {
  119.     DTPBRec pb;
  120.     OSErr err;
  121.     short refNum;
  122.     
  123.     pb.ioCompletion = NULL;
  124.     pb.ioVRefNum = vRefNum;
  125.     pb.ioNamePtr = NULL;
  126.     err= PBDTGetPath(&pb);                // Puts DT refnum into pb.ioDTRefNum
  127.     if( err ) return err;
  128.     refNum = pb.ioDTRefNum;
  129.     
  130.     pb.ioCompletion = NULL;
  131.     pb.ioDTRefNum = refNum;
  132.     pb.ioIndex = 0;
  133.     pb.ioFileCreator = sig;
  134.     pb.ioNamePtr = &file->name;
  135.     err= PBDTGetAPPLSync(&pb);                        // Find it!
  136.     
  137.     if( err == fnfErr )
  138.         err = afpItemNotFound;                        // Bug in PBDTGetAPPL
  139.     if( err )
  140.         return err;                                    // Returns afpItemNotFound if app wasn't found.
  141.  
  142.     file->vRefNum = vRefNum;
  143.     file->parID = pb.ioAPPLParID;
  144.     return noErr;
  145. }
  146.  
  147.  
  148.    ////////////////////////////////////////////////////////////
  149.   //    LaunchIt                                            //
  150.  //            Launch app once we have a location               //
  151. ////////////////////////////////////////////////////////////
  152. static OSErr
  153. LaunchIt( const FSSpecPtr fileSpec, LaunchFlags launchControlFlags, ProcessSerialNumber *psn )
  154. {
  155.     LaunchParamBlockRec pb;
  156.     OSErr err;
  157.     
  158.     pb.launchBlockID = extendedBlock;
  159.     pb.launchEPBLength = extendedBlockLen;
  160.     pb.launchFileFlags = launchNoFileFlags;
  161.     pb.launchControlFlags = launchControlFlags | launchNoFileFlags;
  162.     pb.launchAppSpec = fileSpec;
  163.     pb.launchAppParameters = NULL;
  164.     
  165.     err= LaunchApplication(&pb);
  166.     if( !err )
  167.         *psn = pb.launchProcessSN;
  168.     return err;
  169. }
  170.  
  171.  
  172.    ////////////////////////////////////////////////////////////
  173.   //    SignatureToApp                                        //
  174.  //            Main routine. Find app, launching if need be   //
  175. ////////////////////////////////////////////////////////////
  176. OSErr
  177. SignatureToApp( OSType sig, ProcessSerialNumber *psn, FSSpec *fileSpec, Boolean *launched,
  178.                 Sig2App_Mode mode,
  179.                 LaunchFlags launchControlFlags )
  180. {
  181.     ProcessSerialNumber dummyPSN;
  182.     OSErr err;
  183.     short sysVRefNum, vRefNum, index;
  184.     FSSpec file;
  185.     Boolean hasDesktopDB;
  186.     
  187.     if( launched )
  188.         *launched = false;
  189.     if( psn == NULL )
  190.         psn = &dummyPSN;                                // Allow psn parameter to be NIL
  191.     
  192.     // First see if it's already running:
  193.     
  194.     err= FindRunningAppBySignature(sig,psn,fileSpec);
  195.     
  196.     if( err==noErr )
  197.         if( (launchControlFlags & launchDontSwitch) == 0 )
  198.             return SetFrontProcess(psn);                // They wanted to switch to it…
  199.  
  200.     if( err != procNotFound || mode<=Sig2App_FindProcess )
  201.         return err;
  202.     
  203.     // Well, it's not running but it's okay to launch it. Let's have a look around:
  204.     
  205.     if( err= GetSysVolume(&sysVRefNum) ) return err;    // Find boot volume
  206.     vRefNum = sysVRefNum;                                // Start search with boot volume
  207.     index = 0;
  208.     do{
  209.         if( index==0 || vRefNum != sysVRefNum ) {
  210.             if( err= VolHasDesktopDB(vRefNum,&hasDesktopDB) )
  211.                 return err;
  212.             if( hasDesktopDB ) {                        // If volume has a desktop DB,
  213.                 err= FindAppOnVolume(sig,vRefNum, &file);        // ask it to find app
  214.                 if( err==noErr ) {                                // If found,
  215.                     if( fileSpec )
  216.                         *fileSpec = file;
  217.                     if( mode==Sig2App_LaunchApplication ) {
  218.                         if( launched )
  219.                             *launched = true;
  220.                         err= LaunchIt(&file,launchControlFlags,psn);        // Launch it!
  221.                     }
  222.                     return err;
  223.                 } else if( err != afpItemNotFound )
  224.                     return err;
  225.             }
  226.         }
  227.         err= GetIndVolume(++index,&vRefNum);                // Else go to next volume
  228.     } while( err==noErr );                                // Keep going until we run out of vols
  229.     
  230.     if( err==nsvErr || err==afpItemNotFound )
  231.         err= fnfErr;                                    // File not found on any volume
  232.     return err;
  233. }